package com.itheima.youdianda.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.youdianda.common.Result;
import com.itheima.youdianda.domain.SysMenu;
import com.itheima.youdianda.domain.SysRole;
import com.itheima.youdianda.domain.SysRoleMenu;
import com.itheima.youdianda.dto.SysMenuDto;
import com.itheima.youdianda.dto.SysRoleDto;
import com.itheima.youdianda.service.SysMenuService;
import com.itheima.youdianda.service.SysRoleMenuService;
import com.itheima.youdianda.service.SysRoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 袁鹏
 * @date 2022-09-07-1:48
 */
@RestController
@RequestMapping("sys_role")
public class SysRoleController {
    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysMenuService sysMenuService;

    @GetMapping("/list")
    //@Cacheable(cacheNames = "rolePage", key = "#page + '_' +#limit", condition = "#name == null || #name.trim().length() == 0")
    public Result list(@RequestParam Integer page, @RequestParam Integer limit, String name){
        Page<SysRole> pageInfo = new Page<>(page, limit);
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(name), SysRole::getName, name);
        sysRoleService.page(pageInfo, queryWrapper);
        Map<String, Object> map = new HashMap<>();
        map.put("count", pageInfo.getTotal());
        map.put("totalPages", pageInfo.getPages());
        map.put("pageSize", pageInfo.getSize());
        map.put("currentPage", pageInfo.getCurrent());
        map.put("data", pageInfo.getRecords());
        return Result.ok(map);
    }


    @PostMapping("/update")
    //@Caching(evict = {
    //        @CacheEvict(cacheNames = "rolePage", allEntries = true),
    //        @CacheEvict(cacheNames = "allRole", allEntries = true),
    //        @CacheEvict(cacheNames = "rowInfo", key = "#sysRole.id")})
    public Result updateRole(@RequestBody SysRoleDto sysRole){
        sysRoleService.updateById(sysRole);
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, sysRole.getId());
        sysRoleMenuService.remove(queryWrapper);
        sysRoleMenuService.addRoleMenus(sysRole.getId(), sysRole.getMenuids());
        return Result.ok("修改成功");
    }


    @GetMapping("/rowInfo")
    //@Cacheable(cacheNames = "rowInfo", key = "#id")
    public Result getRoleInfo(@RequestParam String id){
        SysRoleDto byId = sysRoleService.getRoleDto(id);
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, id);
        Set<Integer> menuIds = sysRoleMenuService.list(queryWrapper).stream().map(SysRoleMenu::getMenuId).map(Integer::parseInt).collect(Collectors.toSet());
        //LambdaQueryWrapper<SysMenu> queryWrapper2 = new LambdaQueryWrapper<>();
        //queryWrapper2.in(SysMenu::getId, menuIds);
        Map<Integer, List<SysMenuDto>> parentMap = new HashMap<>();
        Map<Integer, SysMenuDto> idMap = new HashMap<>();
        sysMenuService.getAllMenus().stream().filter(m -> menuIds.contains(m.getId())).forEach(m -> {
            if(parentMap.containsKey(m.getPid())){
                parentMap.get(m.getPid()).add(m);
            }else{
                List<SysMenuDto> list = new ArrayList<>();
                parentMap.put(m.getPid(), list);
                list.add(m);
            }
            idMap.put(m.getId(), m);
        });
        byId.setAuthList(new ArrayList<SysMenuDto>());
        for (Integer parentId : parentMap.keySet()) {
            if(idMap.containsKey(parentId)){
                idMap.get(parentId).setChildren(parentMap.get(parentId));
            }else{
                byId.getAuthList().addAll(parentMap.get(parentId));
            }
        }
        return Result.ok(byId);
    }


    @GetMapping("/allData")
    //@Cacheable(cacheNames = "allRole", keyGenerator = "commonKeyGenerator")
    public Result getAllRoleInfo(){
        List<SysRole> list = sysRoleService.list();
        return Result.ok(list);
    }

    @PostMapping("/add")
    //@Caching(evict = {
    //        @CacheEvict(cacheNames = "rolePage", allEntries = true),
    //        @CacheEvict(cacheNames = "allRole", allEntries = true),
    //        @CacheEvict(cacheNames = "rowInfo", key = "#sysRole.id")})
    public Result addRole(@RequestBody Map<String, Object> map){
        SysRole sysRole = new SysRole();
        sysRole.setName((String) map.get("name"));
        sysRole.setDescription((String) map.get("description"));
        sysRoleService.save(sysRole);
        sysRoleMenuService.addRoleMenus(sysRole.getId(), (List<String>) map.get("menuids"));
        return Result.ok("添加成功");
    }

    @GetMapping("/del")
    //@Caching(evict = {
    //        @CacheEvict(cacheNames = "rolePage", allEntries = true),
    //        @CacheEvict(cacheNames = "allRole", allEntries = true),
    //        @CacheEvict(cacheNames = "rowInfo", key = "#id")})
    public Result deleteRole(@RequestParam String id){
        sysRoleService.removeById(id);
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, id);
        sysRoleMenuService.remove(queryWrapper);
        return Result.ok("删除成功");
    }
}
